#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "../inc/parse.h"
#include "../inc/assistant.h"
#include "../inc/scanner.h"


int
delimLine(char ** args, char * line, parseFn * fnparse, int argsamount)
{
	int argsqtty = 0;
	int parsed = 1, i=0;
	char *auxline;
	scannerADT scanner;
	
	if ( Precondicion((scanner = NewScanner())) ) /* creo el scanner */
		return 0;
		
	if ( (auxline = calloc(strlen(line)+1, sizeof(char))) == NULL )
		return 0;
	
	while (line[i] != '\n' && line[i] != '\0')
	{
		if (line[i] == '#')
			auxline[i] = ' ';
		else
			auxline[i] = line[i];
		i++;
	} 
	
	SetScannerString(scanner, auxline); /* Inicializo string para separarlo en tokens */	
	
	while( MoreTokensExist(scanner) && argsqtty < argsamount )
	{	
		args[argsqtty] = ReadToken(scanner);
		
		if ( !fnparse[argsqtty]((const char *)args[argsqtty++]))
			parsed = 0;
		
	}
	
	if (parsed == 0 || MoreTokensExist(scanner) )
	{
		FreeScanner(scanner); /* Libero el scanner */
		return 0;
	}
	
	free(auxline);
	FreeScanner(scanner); /* Libero el scanner */	 	
	return 1;
}

int
parseName(const char * name)
{
	int i;
	int rta = 1;
	
	
	for (i = 0 ; name[i] != '\0' && i < AIR_MAX ; i++)
		if ( !isalpha(name[i]) || !isupper(name[i]) )
			rta = 0;
			
	if ( name[i] != '\0' )
		rta = 0;
		
	return rta;
}

int
parseLatitude(const char * lat)
{
	float latitude;
	int rta = 1;
	
	if ( !sscanf(lat, "%g", &latitude) )
		return 0;
		
	if ( latitude < (LAT_MIN - EPSILON) || latitude > (LAT_MAX + EPSILON) )
		rta = 0;
		
	return rta;
}

int
parseLongitude(const char * lng)
{
	float longitude;
	int rta = 1;
	
	if ( !sscanf(lng, "%g", &longitude) )
		return 0;
		
	if ( longitude < (LNG_MIN - EPSILON) || longitude > (LNG_MAX + EPSILON) )
		rta = 0;
		
	return rta;
}

int
parseFnum(const char * num)
{
	int numvalue;
	
	if ( !sscanf(num, "%d", &numvalue) )
		return 0;
		
	if ( numvalue <= 0 )
		return 0;
		
	return 1;
}

int
parseDays(const char * wdays)
{
	int repeated[DAYS] = {0};
	char * days[DAYS] = {"Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa"};
	char aux[WEEKDAYS_MAX] = {0};
	int cantdays = 0;
	int i, dayfound = 0;
	
	if (strlen(wdays) > WEEKDAYS_MAX)
		return 0;
	
	/* Se necesita destruir el string wdays para parsearlo con strtok */
	strncpy(aux, wdays, WEEKDAYS_MAX);
	
	/* se lo parte al string delimitandolo por - */
	if ( (wdays = strtok(aux, "-\0")) == NULL)
		return 0;
	else if ( strlen(wdays) < 2) /*si el length del string obtenido es mayor a 2, es error */
		return 0;
	else
		for (i = 0; !dayfound && i < DAYS ; i++) /* se compara para verificar que sea dia valido */
			if( strcmp(wdays, days[i] ) == 0 )
				repeated[i] = dayfound = 1;
	
	/* Aumenta la cantidad de dias en que hay vuelo */
	cantdays++;
	
	/* Si el primer dia que leyo no fue valido, error */
	if( !dayfound )
		return 0;
	
	/* Mientras haya dias a parsear... */
	while ( dayfound && (wdays = strtok(NULL, "-\0")) != NULL )
	{
		dayfound = 0;
		
		if ( strlen(wdays) < 2)
			return 0;
		else
		{	
			for (i = 0 ;  !dayfound && i < DAYS ; i++) /* se compara para verificar que sea dia valido */
			{	
				if( strcmp(wdays, days[i] ) == 0 )
				{	
					if (repeated[i] == 1)
						return 0;
					else
						repeated[i] = dayfound = 1;
				}
			}
		}	
		 
		cantdays++;
	}
	
	/* Si se pusieron mas dias que los 7 de la semana, error! */
	if (cantdays > DAYS)
		dayfound = 0;
		
	return dayfound;
}

int
parseDep(const char * deptime)
{
	int hour, minutes;
	
	if( strlen(deptime) < (DEPARTURE_MAX - 1) )
		return 0;
	
	if ( sscanf(deptime, "%2d:%2d", &hour, &minutes) != 2 )
		return 0;
		
	if (hour < 0 || hour >= 24 || minutes < 0 || minutes > 59)
		return 0;
		
	return 1;
}

int
parseFtime(const char * ftime)
{
	int timeaux;
	char c, hmin, lmin;
	
	/* Un vuelo comun no puede tener otro formato que xxhyym o yym, nunca xxxhyym 
	 * ni otra variante
	 */
	if (strlen(ftime) > FTIME_MAX)
		return 0;
	
	if ( sscanf(ftime, "%d%c", &timeaux, &c) != 2 )
		return 0;
	
	/* si se scanearon horas...*/
	if (c == 'h')
	{
		/* si es una hora negativa, error */
		if (timeaux < 0)
			return 0;
		
		/* si no, procedo a scanear los minutos */	
		if ( sscanf(ftime, "%*d%*c%c%c%c", &hmin, &lmin, &c) != 3 )
			return 0;
		
		/* si no es una m de minutos, error */	
		if (c != 'm')
			return 0;
		else if ( hmin < '0' || hmin > '5' || lmin < '0' || lmin > '9') /* si los minutos son negativos o mayores a 59, error */
			return 0;
	}
	else if (c == 'm')
	{
		if ( strlen(ftime) < (FTIME_MAX / 2) || timeaux < 0 || timeaux > 59)
			return 0;
	}
	/* no era ni una 'h' ni una 'm' */
	else
		return 0;
		
	return 1;
}
		
	
int
parsePrice(const char * price)
{
	float prc;
	
	if ( !sscanf(price, "%g\n", &prc ) )
		return 0;
		
	if (prc < 0)
		return 0;
		
	return 1;
}

int 
parsePrio(const char * prio)
{
	int i, found = 0;
	char * priochoice[PRIO_MAX] = {"ft", "pr", "tt"};
	
	for (i = 0 ; i < PRIO_MAX ; i++)
	{
		if (strcmp(priochoice[i], prio) == 0 )
		{	
			/* se usa break para que quede el valor i-esimo donde encontro prioridad */
			found = i+1;
			break;
		}
	}
			
	return found;
}

	
